#ifndef __CONNECT_POOL_H__
#define __CONNECT_POOL_H__

#include "mysqlDataBase.h"
#include <memory>           // 智能指针
#include <queue>            // 队列
#include <string>
#include <mutex>            // 锁
#include <condition_variable>   // 条件变量
#include <thread>           //线程类

using namespace std;

class ConnectPool
{

public:
    /* 提供一个静态方法，让外部调用唯一实例 */
    static ConnectPool * getConnectPool();

    /* 删除拷贝构造：因为拷贝构造函数也可以创建实例对象，所以要把拷贝构造删除或私有化 */
    ConnectPool(const ConnectPool & obj) = delete;

    /* 删除赋值：原因同拷贝构造，实现只创建一个连接池实例对象 */
    ConnectPool & operator= (const ConnectPool & obj) = delete;

    /* 析构函数 */
    ~ConnectPool();
    
public:
    /* 从连接池中取出一个Mysql连接 */
    std::shared_ptr<mysqlDataBase> getConnection();

private:
    /* 构造函数私有化 */
    ConnectPool();

    /* 添加连接到连接池中 */
    bool addConnection();

    /* 生产线程入口 - 向数据库连接池生产连接句柄 */
    void produceConnection();

    /* 回收线程入口（回调函数） - 回收数据库连接池的连接 */
    void recycleConnection();

    /* 解析配置文件 */
    bool parseConfigFile(const std::string & path);

private:

    /* 连接池内部维护的数据库连接句柄 */
    queue<mysqlDataBase *> m_connectQueue;

    /* 锁 */
    mutex m_mutex;

    /* 条件变量 */
    condition_variable m_cond_produce;      //生产者条件变量 - 连接池的连接不够的时候
    condition_variable m_cond_consume;      //消费者条件变量 = 连接池有多余连接的时候

    /* 配置文件的私有属性 */
    std::string m_hostname;     // 主机地址IP，本地可以写localhost（域名）或127.0.1
    const char * m_passwd;  
    std::string m_username;     // 连接服务器的用户名(一般是root)
    std::string m_passwd;       // 服务器用户的密码
    int m_port;                 // mysql的服务器监听的端口，=0默认为3306
    std::string m_dbname;       // 数据库的名字
    int m_minSize;
    int m_maxSize;
    int m_maxIdleTime;



};


#endif